<?php

require_once( 'io.php' );

class Project
{
	private 	$sProjectName				= null;
	private 	$sProjectDir				= null;
	private 	$sProjectFilePath		= null;
	
	//------------------------------------------------------------------------------
	/**
	 * Initialize the Project class using the project directory relative to the content directory
	 *
	 * @param string $sProjectDir The project dir relative to the content dir
	 * @param ServerResponse $oResponse A server response to send messages to the client
	 * @return bool true if ok and false if there was an error
	 */
	public function setProjectDir( $sProjectDir, $oResponse = null )
	{
		$sProjectDir = FileManager::getContentPath( $sProjectDir );
		
		// Exists ?
		if ( !file_exists( $sProjectDir ) )
		{
			if ( $oResponse != null )
				$oResponse->error( 'The project directory does not exist : '.$sProjectDir );
			return false;
		}
		// Dir ?
		if ( !is_dir( $sProjectDir ) )
		{
			if ( $oResponse != null )
				$oResponse->error( 'The project path is not a directory : '.$sProjectDir );
			return false;
		}
		// Readable ?
		if ( !is_readable( $sProjectDir ) )
		{
			if ( $oResponse != null )
				$oResponse->error( 'The project directory is not readable : '.$sProjectDir );
			return false;
		}
		// Writable ?
		if ( !is_writable( $sProjectDir ) )
		{
			if ( $oResponse != null )
				$oResponse->error( 'The project directory is not writable : '.$sProjectDir );
			return false;
		}
		
		$this->sProjectName = FileManager::getFileOrDirName( $sProjectDir );
		
		// Project Name ok ?
		if ( $this->sProjectName == null )
		{
			if ( $oResponse != null )
				$oResponse->error( 'Cannot get the project name from path : '.$sProjectDir );
			return false;
		}
		$this->sProjectDir = $sProjectDir;
		
		// Find project.xml
		$this->sProjectFilePath = $sProjectDir.'/project.xml';
		// Exists ?
		if ( !file_exists( $this->sProjectFilePath ) )
		{
			if ( $oResponse != null )
				$oResponse->error( 'The project.xml does not exist in the dir : '.$sProjectDir );
			return false;
		}
		// File ?
		if ( !is_file( $this->sProjectFilePath ) )
		{
			if ( $oResponse != null )
				$oResponse->error( 'The project.xml in the dir "'.$sProjectDir.'" is not a file.' );
			return false;
		}
		// Readable ?
		if ( !is_readable( $this->sProjectFilePath ) )
		{
			if ( $oResponse != null )
				$oResponse->error( 'The project.xml in the dir "'.$sProjectDir.'" is not readable.' );
			return false;
		}
		// Writable ?
		if ( !is_writable( $this->sProjectFilePath ) )
		{
			if ( $oResponse != null )
				$oResponse->error( 'The project.xml in the dir "'.$sProjectDir.'" is not writable.' );
			return false;
		}
		
		return true;
	}
	
	//------------------------------------------------------------------------------
	public function renameFileOrDir( $oResponse, $sPath, $sNewName )
	{
		assert( $this->sProjectFilePath != null );
		assert( $this->sProjectDir != null );
		return true;
	}
	
	//------------------------------------------------------------------------------
	public function renameProject( $oResponse, $sNewName )
	{
		assert( $this->sProjectFilePath != null );
		assert( $this->sProjectDir != null );
		return true;
	}
	
	//------------------------------------------------------------------------------
	private function isFileValidForProject( $sFileName )
	{
		return $sFileName != '..' && substr( $sFileName, 0, 1 ) != '.' && substr( $sFileName, 0, 2 ) != '__' && $sFileName != 'project.xml';
	}
	
	//------------------------------------------------------------------------------
	/**
	 * (recursive)
	 */
	private function buildProjectXml( $oResponse, $sPath, $sName, $sTabs = '' )
	{
		$sXml = '';
		
		if ( is_dir( $sPath ) )
		{
			$sXml .= $sTabs."<dir name='".$sName."'>\n";
			
			$oDir = new DirectoryIterator( $sPath );
		
			// Dirs
			while ( $oDir->valid() )
			{
				if ( $oDir->isDir() && $this->isFileValidForProject( $oDir->getFilename() ) )
					$sXml .= $this->buildProjectXml( $oResponse, $oDir->getPathname(), $oDir->getFilename(), $sTabs."\t" );
				$oDir->next();
			}
			$oDir->rewind();
			
			// Files
			while ( $oDir->valid() )
			{
				if ( $oDir->isFile() )
					$sXml .= $this->buildProjectXml( $oResponse, $oDir->getPathname(), $oDir->getFilename(), $sTabs."\t" );
				$oDir->next();
			}
			
			$sXml .= $sTabs."</dir>\n";
		}
		else if ( is_file( $sPath ) )
		{
			$sXml .= $sTabs."<file name='".$sName."'/>\n";
		}
		
		return $sXml;
	}
	
	//------------------------------------------------------------------------------
	public function synchronizeProjectFromFileSystem( $oResponse )
	{
		assert( $this->sProjectFilePath != null );
		assert( $this->sProjectDir != null );
		
		$oFile = fopen( $this->sProjectFilePath, 'wc' );
		
		if ( $oFile == null )
		{
			$oResponse->error( 'Cannot open the project.xml file : '.$this->sProjectFilePath );
			return false;
		}
		
		$sProjectXml = "<pulse>\n";
		$sProjectXml .= "\t<project name='".$this->sProjectName."'>\n";
		
		$oDir = new DirectoryIterator( $this->sProjectDir );
		
		// Dirs
		while ( $oDir->valid() )
		{
			if ( $oDir->isDir() && $this->isFileValidForProject( $oDir->getFilename() ) )
				$sProjectXml .= $this->buildProjectXml( $oResponse, $oDir->getPathname(), $oDir->getFilename(), "\t\t" );
			$oDir->next();
		}
		$oDir->rewind();
		
		// Files
		while ( $oDir->valid() )
		{
			if ( $oDir->isFile() && $oDir->getFilename() != 'project.xml'  )
				$sProjectXml .= $this->buildProjectXml( $oResponse, $oDir->getPathname(), $oDir->getFilename(), "\t\t" );
			$oDir->next();
		}
		
		$sProjectXml .= "\t</project>\n";
		$sProjectXml .= "</pulse>\n";
		
		//fwrite( $oFile, $sProjectXml );
		
		fclose( $oFile );
		
		file_put_contents( $this->sProjectFilePath, $sProjectXml );
		
		return true;
	}
}
?>